package NuvemDeFumacaInteligencia;

import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

public class Mapa {
	
	int linha, coluna;
	HashMap<Point, String> mapaDePosicoes;
	
	public HashMap<Point, String> getMapaDePosicoes() {
		return mapaDePosicoes;
	}

	public Mapa(){
		mapaDePosicoes = new HashMap<Point, String>();
	}

	public int linha()
	{
		return linha;
	}
	public void linha(int linha)
	{
		this.linha = linha;
	}
	public int coluna() 
	{
		return coluna;
	}
	public void coluna(int coluna) 
	{
		this.coluna = coluna;
	}
	public void insere(String caractereDaVez, Point point) {
	
		mapaDePosicoes.put(point, caractereDaVez);
		
	}

	public String buscaObjetoNaPosicao(Point point) {
		
		return mapaDePosicoes.get(point);
		
	}

	public ArrayList<Point> posicaoDeTodosOsAvioes() {
		
		Iterator<Point> iterator = mapaDePosicoes.keySet().iterator();
		
		ArrayList<Point> casasDosAvioes = new ArrayList<Point>();
		
		while(iterator.hasNext()){
			
			Point pointDaVez = iterator.next();
			
			if(buscaObjetoNaPosicao(pointDaVez) == "Aviao"){
				
				casasDosAvioes.add(pointDaVez);
			}
		
		}
		
		return casasDosAvioes;
	}
	
	public ArrayList<Point> posicaoDeTodosAsNuvens() {
		
		Iterator<Point> iterator = mapaDePosicoes.keySet().iterator();
		
		ArrayList<Point> casasDasNuvens = new ArrayList<Point>();
		
		while(iterator.hasNext()){
			
			Point pointDaVez = iterator.next();
			
			if(buscaObjetoNaPosicao(pointDaVez) == "Nuvem"){
				
				casasDasNuvens.add(pointDaVez);
			}
		
		}
		
		return casasDasNuvens;
	}

	public Mapa mapaDoDiaSeguinte() throws CloneNotSupportedException {
		
		Mapa novoMapa = (Mapa) this.clone();
	
		Object[] posicoes = novoMapa.posicaoDeTodosAsNuvens().toArray();
		
		Object[] movimentos = movimentos().toArray();
		
		for(int i = 0; i < this.posicaoDeTodosAsNuvens().size(); i++){
			for(int j = 0; j < this.movimentos().size(); j++){
				
				Point pointDaVez1 = (Point) posicoes[i];
				Point pointDaVez2 = (Point) movimentos[j];
				
				novoMapa.insere("Nuvem", somaPoints(pointDaVez1, pointDaVez2));
			}
			
		
		}
		
		
		return novoMapa;
	}

	private ArrayList<Point> movimentos(){ 
		
		ArrayList<Point> movimentos = new ArrayList<Point>();
				movimentos.add(new Point(1,0));
				movimentos.add(new Point(-1,0)); 
				movimentos.add(new Point(0,1));
				movimentos.add(new Point(0, -1));
				
		return movimentos;	
				
	}

	public Point somaPoints(Point point1, Point point2)
	{
		
		int volorX = (int)point1.getX() + (int)point2.getX();
		int volorY = (int)point1.getY() + (int)point2.getY();
		
		Point valorFinal = new Point(volorX, volorY);
		
		return valorFinal;
		
		
	}

	private boolean verificaSePrimeiroAeroportoFoiCoberto(Mapa aMapa)
	{
		
		return this.posicaoDeTodosOsAvioes().size() == aMapa.posicaoDeTodosOsAvioes().size();
		
		
	}

	public int numeroDeDiasParaCobrirOPrimeiroAeroporto() throws CloneNotSupportedException
	{
		
		Mapa novoMapa = this.mapaDoDiaSeguinte();
		
		int diasPrimeiroAeroporto = 1;
	
		while(verificaSePrimeiroAeroportoFoiCoberto(novoMapa)){
			
			novoMapa = novoMapa.mapaDoDiaSeguinte();
			
			diasPrimeiroAeroporto++;
			
		}
		
		return diasPrimeiroAeroporto;
	}

	@Override
	protected Object clone() {
		
		Mapa novoMapa = new Mapa();
		novoMapa.coluna = this.coluna;
		novoMapa.linha = this.linha;
		novoMapa.mapaDePosicoes.putAll(this.mapaDePosicoes);
		
		return novoMapa;
	}

	public boolean mapeia(){ return true;}

	public int numeroDeDiasParaCobrirTodosOsAeroportos() throws CloneNotSupportedException {
		
		Mapa novoMapa = this.mapaDoDiaSeguinte();
		
		int diasTodosAeroportos = 1;
	
		while(verificaSeTodosOsAeroportosForamCobertos(novoMapa)){
			
			novoMapa = novoMapa.mapaDoDiaSeguinte();
			
			diasTodosAeroportos++;
			
		}
		
		return diasTodosAeroportos;
	}

	private boolean verificaSeTodosOsAeroportosForamCobertos(Mapa aMapa) {
		
		return aMapa.posicaoDeTodosOsAvioes().size() > 0;
	
	}
}